package com.ssy.lingxi.order.serviceimpl.base;

import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.order.entity.OrderDO;
import com.ssy.lingxi.order.entity.OrderInvoiceDO;
import com.ssy.lingxi.order.model.constant.InvoiceKindEnum;
import com.ssy.lingxi.order.model.constant.InvoiceTypeEnum;
import com.ssy.lingxi.order.model.dto.OrderInvoiceDTO;
import com.ssy.lingxi.order.model.vo.basic.request.OrderInvoiceVO;
import com.ssy.lingxi.order.model.vo.basic.response.OrderInvoiceDetailVO;
import com.ssy.lingxi.order.repository.OrderInvoiceRepository;
import com.ssy.lingxi.order.service.base.IBaseOrderInvoiceService;
import com.ssy.lingxi.order.service.feign.ISettleAccountFeignService;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 订单发票相关接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-19
 */
@Service
public class BaseOrderInvoiceServiceImpl implements IBaseOrderInvoiceService {
    @Resource
    private OrderInvoiceRepository orderInvoiceRepository;

    @Resource
    private ISettleAccountFeignService settleAccountFeignService;

    /**
     * 校验并生成订单发票，调用方需要保存OrderDO
     *
     * @param order      订单
     * @param hasInvoice 是否有发票
     * @param invoiceVO  订单发票接口参数
     * @param isCreate   是否新增，true-新增，false-修改
     * @return 校验结果
     */
    @Override
    public Wrapper<Void> checkOrderInvoice(OrderDO order, Boolean hasInvoice, OrderInvoiceVO invoiceVO, boolean isCreate) {
        if(hasInvoice && invoiceVO == null) {
            return Wrapper.fail(ResponseCode.ORDER_INVOICE_CAN_NOT_BE_EMPTY);
        }

        return checkOrderInvoice(order, invoiceVO, isCreate);
    }

    /**
     * 校验并生成订单发票，调用方需要保存OrderDO
     *
     * @param order     订单
     * @param invoiceVO 订单发票接口参数
     * @param isCreate  是否新增，true-新增，false-修改
     * @return 校验结果
     */
    @Override
    public Wrapper<Void> checkOrderInvoice(OrderDO order, OrderInvoiceVO invoiceVO, boolean isCreate) {
        if(!isCreate) {
            orderInvoiceRepository.deleteByOrder(order);
        }

        if(invoiceVO == null) {
            order.setInvoice(null);
            return Wrapper.success();
        }

        OrderInvoiceDO invoice = new OrderInvoiceDO();
        invoice.setInvoiceId(invoiceVO.getInvoiceId());
        invoice.setOrder(order);
        invoice.setInvoiceKind(invoiceVO.getInvoiceKind());
        invoice.setInvoiceType(invoiceVO.getInvoiceType());
        invoice.setTitle(invoiceVO.getTitle());
        invoice.setTaxNo(StringUtils.hasLength(invoiceVO.getTaxNo()) ? invoiceVO.getTaxNo() : "");
        invoice.setBank(StringUtils.hasLength(invoiceVO.getBank()) ? invoiceVO.getBank().trim() : "");
        invoice.setAccount(StringUtils.hasLength(invoiceVO.getAccount()) ? invoiceVO.getAccount().trim() : "");
        invoice.setAddress(StringUtils.hasLength(invoiceVO.getAddress()) ? invoiceVO.getAddress().trim() : "");
        invoice.setPhone(StringUtils.hasLength(invoiceVO.getPhone()) ? invoiceVO.getPhone().trim() : "");
        invoice.setDefaultInvoice(invoiceVO.getDefaultInvoice());

        order.setInvoice(invoice);

        return Wrapper.success();
    }

    /**
     * （转单） - 交易并生成订单发票，调用方需要保存OrderDO
     *
     * @param order   转单后的订单
     * @param invoiceDTO 上游供应商发票
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> transferOrderInvoice(OrderDO order, OrderInvoiceDTO invoiceDTO) {
        if(invoiceDTO == null) {
            order.setInvoice(null);
            return Wrapper.success();
        }

        OrderInvoiceDO invoice = new OrderInvoiceDO();
        invoice.setInvoiceId(invoiceDTO.getInvoiceId());
        invoice.setOrder(order);
        invoice.setInvoiceKind(invoiceDTO.getInvoiceKind());
        invoice.setInvoiceType(invoiceDTO.getInvoiceType());
        invoice.setTitle(invoiceDTO.getTitle());
        invoice.setTaxNo(invoiceDTO.getTaxNo());
        invoice.setBank(StringUtils.hasLength(invoiceDTO.getBank()) ? invoiceDTO.getBank().trim() : "");
        invoice.setAccount(StringUtils.hasLength(invoiceDTO.getAccount()) ? invoiceDTO.getAccount().trim() : "");
        invoice.setAddress(StringUtils.hasLength(invoiceDTO.getAddress()) ? invoiceDTO.getAddress().trim() : "");
        invoice.setPhone(StringUtils.hasLength(invoiceDTO.getPhone()) ? invoiceDTO.getPhone().trim() : "");
        invoice.setDefaultInvoice(invoiceDTO.getDefaultInvoice());

        order.setInvoice(invoice);

        return Wrapper.success();
    }

    /**
     * 查询订单发票信息
     *
     * @param order 订单
     * @return 查询结果
     */
    @Override
    public OrderInvoiceDetailVO getOrderInvoice(OrderDO order) {
        OrderInvoiceDO invoice = orderInvoiceRepository.findFirstByOrder(order);
        if(invoice == null) {
            return null;
        }

        OrderInvoiceDetailVO detailVO = new OrderInvoiceDetailVO();
        detailVO.setInvoiceId(invoice.getInvoiceId());
        detailVO.setInvoiceKind(invoice.getInvoiceKind());
        detailVO.setInvoiceKindName(InvoiceKindEnum.getNameByCode(invoice.getInvoiceKind()));
        detailVO.setInvoiceType(invoice.getInvoiceType());
        detailVO.setInvoiceTypeName(InvoiceTypeEnum.getNameByCode(invoice.getInvoiceType()));
        detailVO.setTitle(invoice.getTitle());
        detailVO.setTaxNo(StringUtils.hasLength(invoice.getTaxNo()) ? invoice.getTaxNo() : "");
        detailVO.setBank(invoice.getBank());
        detailVO.setAccount(invoice.getAccount());
        detailVO.setAddress(invoice.getAddress());
        detailVO.setPhone(invoice.getPhone());
        detailVO.setDefaultInvoice(invoice.getDefaultInvoice());
        return detailVO;
    }

    /**
     * （转单）校验、查询上游供应商发票信息
     *
     * @param orders 订单列表
     * @return 查询结果
     */
    @Override
    public Wrapper<Map<Long, OrderInvoiceDTO>> findSupplyOrderInvoice(List<OrderDO> orders) {
        //发票是会员所有角色通用的，所以只需要根据会员Id来判断匹配查询结果
        Wrapper<List<OrderInvoiceDTO>> invoiceResult = settleAccountFeignService.findMemberInvoices(orders.stream().filter(order -> Objects.nonNull(order.getInvoice())).map(OrderDO::getVendorMemberId).distinct().collect(Collectors.toList()));
        if(invoiceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(invoiceResult.getCode(), invoiceResult.getMessage());
        }

        Map<Long, OrderInvoiceDTO> invoiceMap = new HashMap<>();
        for (OrderDO order : orders.stream().filter(order -> Objects.nonNull(order.getInvoice())).collect(Collectors.toList())) {
            OrderInvoiceDTO invoice = invoiceResult.getData().stream().filter(supplyInvoice -> supplyInvoice.getMemberId().equals(order.getVendorMemberId())).findFirst().orElse(null);
            if(invoice == null) {
                return Wrapper.fail(ResponseCode.ORDER_VENDOR_MEMBER_INVOICE_DOES_NOT_EXIST);
            }

            invoiceMap.put(order.getId(), invoice);
        }

        return Wrapper.success(invoiceMap);
    }
}
